<?xml version="1.0" encoding="UTF-8"?>
<html>
    <head>
        <link type="text/css" rel="stylesheet" href="./css/template.css" />
        <link type="text/css" rel="stylesheet" href="./css/SyntaxHighlighter.css" />
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Choisir son interface graphique en Java</title>
        <script language="javascript" src="./js/shInit.js" />
        <script language="javascript" src="./js/shCore.js" />
        <script language="javascript" src="./js/shBrushCpp.js" />
        <script language="javascript" src="./js/shBrushCSharp.js" />
        <script language="javascript" src="./js/shBrushCss.js" />
        <script language="javascript" src="./js/shBrushDelphi.js" />
        <script language="javascript" src="./js/shBrushJava.js" />
        <script language="javascript" src="./js/shBrushJScript.js" />
        <script language="javascript" src="./js/shBrushPhp.js" />
        <script language="javascript" src="./js/shBrushPython.js" />
        <script language="javascript" src="./js/shBrushRuby.js" />
        <script language="javascript" src="./js/shBrushSql.js" />
        <script language="javascript" src="./js/shBrushVb.js" />
        <script language="javascript" src="./js/shBrushXml.js" />
        <keywords>interface graphique, GUI, Matisse, Visual Editor, Léonardi, SwingX</keywords>
        <author>Maxime VIALETTE</author>
    </head>
    <body>
        <div class="chapter">
            <h2>Introduction</h2>
            <p>Dans une application, la partie graphique est aussi importante que la partie
				traitement car c’est cette partie qui reste la plus visible pour l’utilisateur.
				Une application dont l’interface utilisateur n’est pas claire sera fatalement
				peu utilisée. Nous allons voir quelles sont les librairies Java à notre
				disposition pour réaliser l’interfaçage ainsi que ces  certains outils,
				libre ou propriétaire, que vous pourrez utiliser.</p>
        </div>
        <div class="chapter">
            <h2>Les librairies graphiques</h2>
            <p>Aujourd'hui, la majorité des développements graphiques en Java
				utilisent Swing. Vous connaissez peut-être AWT (Abstract Windowing
				Toolkit), l'ancêtre de Swing apparut dès la version 1.0 de Java. Cette
				API graphique est compatible avec toutes les versions de Java, y
				compris Java Mobile Édition. Les composants sont dits « lourds »
				car ils sont dessinés et contrôlés par le système et non par Java.
				C'est pourquoi AWT utilise assez peu de ressources, pourtant il
				se fait vieux et rend difficile l’utilisation d’architecture en couches.</p>
            <p>Le principe MVC (modèle-vue-contrôleur) ne peut pas être respecté
				en AWT. Il se limite aux composants communs à tous les systèmes,
				il faut donc souvent les personnaliser. AWT reste un choix pour les
				systèmes limités.</p>
            <p>Pour lui succéder, Sun a entrepris de développer la librairie Swing.
				Respectant l'architecture vue-contrôleur, Swing est un standard complet.
				Aspect décisif, les composants Swing sont légers (c'est à dire dessinés
				par Java2D et contrôlés en pur Java). De cette caractéristique qui reflète
				l'objectif "Write once, run everywhere" découlent plusieurs
				inconvénients : les composants manquaient d’esthétisme, le rendu
				pouvait paraître lent, etc. Swing consomme beaucoup de mémoire mais
				est-ce aussi lent qu'on le dit. Codée en pur Java et n’utilisant pas de
				fonction native, il est normal qu'elle ne soit pas aussi rapide qu'une API
				graphique native au système d’exploitation. Mais la puissance des
				ordinateurs évoluant rapidement, cela se fait de moins en moins sentir.
				Le choix d’objets graphiques dessinés directement par Java2D fait à la
				fois la force et la faiblesse de Swing : la portabilité du même code, quelques
				soit la plateforme de destination, est possible grâce à Swing, cependant,
				la contrepartie de cette portabilité était un manque de réactivité des
				applications graphique Java. L'utilisateur est souvent frustré lors de
				l'utilisation pour quelques dixièmes de secondes de latence qui sont
				le reflet de l'architecture même de Swing. Cette impression est provoquée
				par exemple lors d'un clic de bouton, si ce dernier effectue quelque chose
				de long comme un accès sur un réseau il faut jouer avec les threads pour
				éviter que l'interface ne se gèle et pose des problèmes de rafraîchissement.
				Java 6 a fait un véritable bond en avant pour aider les programmeurs à
				annuler cet effet. De nombreuses autres nouveautés de Swing dans
				JSE 6 : les "look &amp; feel" qui ont été améliorés car l'apparence dans les
				versions précédente se faisait désuète sans utilisation de librairies
				spécialisées comme JGoodies (une API LGPL) qui permet d’améliorer
				le rendu des objets graphiques.</p>
            <p>Si vous souhaitez mixer des éléments AWT et Swing, sachez qu'il est
				difficile de le faire même si la syntaxe est proche. Les objets se
				superposent, le problème vient de leur nature : les composants
				AWT (lourds) seront toujours en dessous des composants Swing
				(légers) car la machine virtuelle dessine les composants AWT avant
				les composants Swing. Ce problème est résolu dans Java 6 : il est donc
				déconseillé d'avoir AWT et Swing dans la même fenêtre jusqu'à Java 5.</p>
            <p>
                Application en Swing : Aerith
                <img src="./images/aerith.jpg" />
            </p>
            <p>Avec une approche croisée entre AWT et Swing, l'API SWT mise sur
				l'utilisateur en dépit de la portabilité. En effet, cette librairie (initialement
				développée par IBM sous licence libre) possède une partie native. Elle
				permet de réaliser des interfaces plus rapides en utilisant une majorité de
				composants natifs aux différents systèmes d’exploitation pour lesquels
				vous souhaiter destiner votre application. Cette librairie peut également
				dessiner des composants graphiques n'existent pas sur une plateforme.
				Souvent, l'utilisateur pense qu'un logiciel Java développé à l’aide d’SWT
				est un programme natif. Côté développeur et sans l'utilisation de JFace,
				SWT n'est pas aussi agréable à coder que Swing, surtout pour les
				habituer de Swing car les principes de base ne sont pas du tout les
				mêmes. Dû à la partie native, le "garbage collector" Java n'est plus...
				Les objets parents s'occupent de la libération de mémoire de leurs enfants
				lorsqu'on les supprime. Revenons maintenant sur Jface : permettant de
				respecter l'architecture MVC, il améliore le code qui devient
				plus facile à maintenir. Il est plus judicieux de comparer Swing avec
				SWT+JFace (il faudra quand même coder des parties en SWT pour
				les utilisations avancées).</p>
            <p>N'étant ni standard ni indépendant du système d'exploitation,
				l'apparence est différente suivant la plateforme. On doit maintenir autant
				de versions que de systèmes, on perd alors un des grands avantages
				de Java.</p>
            <p>Parmi les problèmes de SWT, certains sont solutionnés par la nouvelle API
				SwingWT. Elle couvre Swing à 90% et offre un pont entre ces deux mondes.
				Un développeur Swing peut alors programmer en utilisant la syntaxe Swing
				puis compiler avec SwingWT (il suffit de remplacer les packages Swing par
				SwingWT). L'application obtenue utilise SWT lors de l'exécution. De plus, un
				programme écrit pour Swing peut être compilé en SWT. A l'inverse, grâce à
				l'API SWTSwing, nous avons désormais le pont dans l'autre sens.
				Dans ce cas, un programme SWT pourra utiliser pour son affichage SWT ou
				Swing sans recompilation.</p>
            <p>
                Application en SWT : Azureus
                <img src="./images/azureus.jpg" />
            </p>
            <p>Maintenant que nous avons vu les avantages et les inconvénients de
				chaque API, vous pourrez choisir précisément l'API qui vous convient.
				Les développeurs Java Mobile et Applets choisirons sûrement AWT. Swing
				sera plus à même de répondre à des projets portables de grande ampleur
				faciles à maintenir. SWT quand à lui, sera parfait pour les petits et grands
				développements ou pour prouver qu'une interface Java peut être aussi
				réactive qu'une interface en C. Finalement SwingWT et SWTSwing seront
				peut-être une façon de réconcilier tout le monde et de profiter à
				la fois des avantages de Swing et d’SWT...</p>
            <div class="subChapter">
                <h3>SwingX</h3>
                <p>SwingX, pour Swing eXtension, est une partie d’un projet développé par
					SwingLabs, visant à créer de nouveaux composants à intégrer rapidement
					dans nos applications. SwingX est basé sur la librairie Swing, l’une des
					API graphiques les plus utilisées.</p>
                <p>Il contient les extensions de l’interface graphique Swing en incluant de
					nouveaux composants qui fournissent des fonctionnalités requises par les
					applications "rich client" (c'est-à-dire des
					applications qui se connectent à des serveurs d'application comme le
					ferait un navigateur web classique, mais en proposant une interface plus
					avancée que le HTML traditionnel).</p>
                <p>Certains codes et concepts de ce projet devraient faire partie des
					futures plateformes de Java.</p>
                <p>Les nouveautés les plus importantes comprennent :</p>
                <ul>
                    <li>le tri ;</li>
                    <li>le filtrage ;</li>
                    <li>la mise en valeur des éléments des  tables ;</li>
                    <li>des arbres ;</li>
                    <li>des listes.</li>
                    <li>chercher/trouver ;</li>
                    <li>l’auto-completion ;</li>
                    <li>le Login / un framework d’authentication ;</li>
                    <li>le composant TreeTable ;</li>
                    <li>le composant panel que l’on peut rendre invisible ;</li>
                    <li>le composant de choix de date (calendrier) ;</li>
                    <li>le composant  "Tip-of-the-Day " (astuce du jour).</li>
                </ul>
                Voici des exemples de composants SwingX :
                <ul>
                    <li>
                        Le calendrier
                        <p>On peut créer un calendrier permettant de sélectionner une date.
							Il apparaît comme un JTextField banal avec un bouton sur le côté et le
							calendrier se déroule lorsque l'on clique dessus.</p>
                        <img src="./images/calendrier.jpg" />
                    </li>
                    <li>
                        Auto-completion
                        <p>L'auto-completion survient lorsque l'on commence à entrer du texte dans
							un champ et que celui-ci se complète automatiquement. C'est le cas
							dans beaucoup de logiciels, comme par exemple lors du choix de la
							langue de l'application.</p>
                        <img src="./images/completion.jpg" />
                    </li>
                    <li>Auto-completion sur un JTextField et une Jlist</li>
                    <li>
                        Panneau de conseils
                        <p>Le composant JXTipOfTheDay permet de créer une boite de dialogue de
							conseils que l'on affiche au lancement de l'application. Il suffit de créer une
							petite base de "Tips" et de les afficher comme on le ferai grâce à un
							JDialog.</p>
                    </li>
                </ul>
            </div>
        </div>
        <div class="chapter">
            <h2>Eclipse RCP</h2>
            <p>Eclipse RCP (Rich Client Platform) est une réelle révolution dans la
				conception d’interface graphique en Java. Entièrement intégré à Eclipse,
				cet outil permet de créer des projets plug-in pour Eclipse, mais aussi des
				applications fenêtrées en standalone. Bien entendu,
				chaque projet étant un plug-in, vous pouvez les réutiliser dans
				n’importe quelle autre application basée sur RCP.</p>
            <p>En utilisant Eclipse RCP, vous pourrez créer des applications en SWT/JFace.
				L’intérêt, comme évoqué plus haut, étant que les composants graphiques
				sont natifs au système d’exploitation (dans le cas où l’OS les supporte),
				sinon ils sont dessinés en Java2D, comme si on utilisait Swing. Cela permet
				d’obtenir des performances élevées. Un autre avantage en utilisant Eclipse
				RCP est de se baser sur l’architecture modulaire d’Eclipse : vous pouvez
				donc profiter des onglets, du système des vues déplaçable,
				des perspectives, de l’éditeur textuel, etc.
				Niveau visuel, l’une des plus grandes force de cette API est la présence de
				PLAF (Pluggable Look n’ feel) qui permet au développeur de créer lui-même
				son propre look n’ feel.</p>
            <p>
                Cependant, cet outil se révèle assez complexe pour les utilisations avancées,
				mais cela tente à être corrigé au fil des versions car cela permet d’accélérer le
				développement de manière considérable en profitant des apports ayant été
				fait à Eclipse.
				Voilà un exemple tout simple de ce que l’on peut faire : une application RCP à
				laquelle on a intégré un plug-in.
                <img src="./images/rcp.jpg" />
            </p>
            <p>
                Pour plus d’information, veuillez consulter les magazines Programmez! N° 84 et
				85 (Mars et Avril 2006) ou visiter l’article suivant :
                <a href="http://www.labo-sun.com/resource-fr-articles-1185-1-eclipse-eclipse-eclipse-rcp.htm" target="_blank">Eclipse RCP</a>
            </p>
        </div>
        <div class="chapter">
            <h2>Léonardi</h2>
            <p>
                Nous allons voir ici un produit permettant de développer rapidement et
				simplement une IHM (Interface Homme-Machine) grâce au produit Leonardi.
				Ce produit conviendra aussi bien aux débutants non familiarisés avec les
				outils de modélisation IHM qu'aux utilisateurs chevronnés qui voudront
				bénéficier de la puissance de Leonardi.
				En effet, ce produit édité par la société Lyria (
                <a href="http://www.lyria.com/" target="_blank">www.lyria.com</a>
                ) est un
				framework Model-Driven ce qui permet le développement de fonctionnalités
				indépendamment de la plate-forme et donc d'automatiser les développements
				des clients légers (applications accessibles via une interface web), lourds
				(applications graphiques exécutées localement) ou riches (compromis entre
				client léger et client lourd).
				Nous pourrons donc faire évoluer ces clients en toute simplicité, ce qui est
				permis par le fait que le moteur Leonardi produit une description XML des
				vues (indépendante de l'afficheur) vers des cibles (SWT, Swing, Eclipse RCP)
				dont nous avons parlé précédemment. De plus, il existe une cinquantaine
				d'actions pré-implementées que l'on pourra utiliser à sa guise et que nous
				n'aurons pas besoin de recoder, ce qui entraîne un bon gain de temps.
            </p>
            <p>Parlons maintenant de l'installation du produit. Tout d'abord, il est important
				de noter qu'il existe quatre versions. La version « free » qui est la déclinaison
				libre du produit Leonardi et qui supporte tous les projets basés sur des
				technologies open source.</p>
            <p>Nous avons également les versions payantes qui correspondent à
				différents types de besoins : la version « agile » utilisée pour les projets
				courts en développement rapide mais aussi pour le prototypage ou le
				maquettage; il y a aussi la version « evolution » essentiellement employée
				pour assurer la migration d'anciennes applications avec forte connotation
				métier (type progiciel). Enfin, la version la plus avancée : la « factory »,
				s'adresse aux projets complexes s'inscrivant sur une longue période de
				développement faisant l’objet d’étapes successives
				structurées, et suivant  un cheminement de type conception, implémentation,
				déploiement, maintenance et évolution des applications.
				Une fois que vous avez choisi la version qui correspond le plus à vos besoins,
				il vous faut l'installer. Pour cela, deux choix s'offrent à vous : n'installer que le
				plug-in pour Eclipse ou bien utiliser le Studio du produit Leonardi qui est une
				application tierce en « stand-alone ».</p>
            <p>
                Pour utiliser le plug-in sous Eclipse, rien de plus simple, il vous suffit de créer
				un nouveau projet, d'aller à l'onglet Plug-in developpement puis de choisir
				l'option Plug-in from existing JAR archives. Sur la nouvelle fenêtre qui
				apparaît, nous appuyons sur Add External et sélectionnons le fichier
				studio.jar qui se trouve dans le dossier préalablement téléchargé et
				décompressé sur le site de lyria
				(
                <a href="http://www.lyria.com/page_complete.php3 id_rubrique=15" target="_blank">Lyria</a>
                ).
				Vous pouvez aussi utiliser l'installeur de Lyria qui installera donc le Studio
				Leonardi sur votre ordinateur. Cette installation suit le schéma classique de
				tout programme et aucune configuration n'est à effectuer.
				Voici un exemple de l'environnement de développement du Studio Leonardi
                <imh src="http://www.lyria.com/IMG/png/studio_navigation_tree.png" />
            </p>
            <p>Une fois le produit installé, vous pouvez commencer à vous familiariser grâce
				à ce tutorial : Voir le numéro de programmez numéro 89 (Septembre 2006).</p>
            <p>
                Parlons maintenant des avantages et inconvénients à utiliser le produit Leonardi.
				Il faut savoir que les projets induisent une problématique fonctionnelle et technique
				dont la spécification est longue, les développeurs doivent donc maîtriser les
				délais et les coûts de leurs travaux.
				Grâce à Leonardi, il est devenu possible, outre le fait de faire évoluer et
				moderniser les anciennes applications entrainant un gain appréciable de temps
				et donc de coût, de concevoir des développements sur des architectures solides
				notamment dans le cadre du cycle en V, qui permet de vérifier à chaque étape la
				conformité aux spécifications de l'étape précédente selon ce modèle :
                <img src="http://upload.wikimedia.org/wikipedia/fr/0/05/Cycle_de_developpement_en_v.jpg" />
                mais aussi pour maîtriser la séparation entre la programmation de son interface
				graphique et le code qui « l'habillera ».
				Malheureusement, tout cela a un coût et le prix des produits Leonardi peut en rebuter
				plus d'un, en effet, il faudra débourser 9 000€ HT pour la version « evolution » et
				12 000€ HT pour la version « factory ».
            </p>
            <ul>
                Produit Leonardi :
                <li>Pré-requis : JVM 1.4+</li>
                <li>Les + : Adaptabilité</li>
                <li>Evolutivité</li>
                <li>Maitrise</li>
                <li>Les - : Prix</li>
            </ul>
        </div>
        <div class="chapter">
            <h2>Les outils WYSIWYG</h2>
            <p>Fini les longues heures à développer une interface graphique (SWING ou
				autre), nous pouvons maintenant  trouver dans un environnement de
				développement intégré  (EDI ou IDE en anglais pour Integrated Development
				Environment) des  outils pour faciliter la création de l'interface graphique
				(GUI en anglais pour Graphical User Interface). En Java, nous avons au
				moins deux combinaisons : Eclipse accompagné de Visual Editor et
				Netbeans incluant Matisse. En un clic vous pourrez ajouter un élément
				graphique à votre interface : fenêtre, champ de texte, bouton, texte
				déroulant, arborescence, etc.</p>
            <div class="subChapter">
                <h3>Visual Editor</h3>
                <p>
                    Visual Editor est un plugin pour développer des interfaces SWING et
					AWT sous Eclipse. Vous pouvez télécharger le plugin à l’adresse
					suivante
                    <a href="http://www.eclipse.org/vep/WebContent/main.php" target="_blank">http://www.eclipse.org/vep/WebContent/main.php</a>
                    . Une fois
					Visual Editor téléchargé, vous décompressez le fichier dans le répertoire
					du logiciel Eclipse. Cet outil présente plusieurs fenêtres facilitant le
					développement. Par défaut, la première fenêtre est un éditeur
					WYSIWYG (What You See Is What You Get) qui permet de construire
					l’application par de simples glissé-déposés. La seconde fenêtre est la
					vue du code source de l’application. Ensuite, nous avons deux vues
					supplémentaires : la vue « Java Beans » qui représente la hiérarchie
					de confinement de l’interface graphique et la vue « properties » qui
					permet d’éditer les propriétés d’un composant.
                </p>
                <p>
                    Par défaut, les
					applications SWT n’utilise pas de layout manager, contrairement aux
					applications Swing qui utilisent le BorderLayout. Si vous choisissez
					un layout
                    <em>null</em>
                    alors vous pourrez positionner vos composants comme
					vous le souhaitez. Par contre, les composants ne seront pas
					redimensionnés, vous devrez gérer le redimensionnement si vous le
					voulez.
                </p>
                <p>Visual Editor contient des dépendances à d’autres des plugins
					Eclipse : EMF (Eclipse Modeling Framework) et GEF
					(Graphical Editing Framework). EMF est un service de génération de
					code de Java pour des applications basées sur un modèle structuré.
					Il vous aide rapidement à transformer vos modèles en code efficace,
					correct en Java. Par exemple, lorsque vous déplacez un composant
					de type bouton dans la vue JavaBeans, le code du bouton sera généré
					automatiquement dans la vue du code source de l’application.</p>
                <p>
                    Concernant GEF, il utilise le plugin « org.eclipse.draw2d ».
					Ce dernier fournit une disposition et une trousse à outils de rendu
					pour montrer des graphiques. GEF  permet de créer des graphiques,
					c’est sur ce plugin que va s’appuyer Visual Editor afin d’effectuer le
					rendu de votre application dans une vue spécifique.
                    <img src="./images/gef.jpg" />
                </p>
            </div>
            <div class="subChapter">
                <h3>Matisse</h3>
                <p>Matisse est le nom donné à l'éditeur visuel de NetBeans. Il vous permet
					de disposer vos composants librement, vous fournissant des règles
					visuelles pour optimiser les espaces entre les composants et l'alignement
					des composants. Matisse libère le développeur de la complexité des
					gestionnaires de layout de Swing. Le développeur utilise un outil de
					conception visuel intuitif pour produire facilement un GUI professionnel,
					et Matisse produira l'implémentation correcte en utilisant un gestionnaire
					de layout.</p>
                <p>Il est composé de  plusieurs vues : une zone de conception,
					une vue  « inspecteur », une palette et une vue « properties ». La zone de
					conception est une fenêtre principale de création et de modification des
					formulaires de l'interface graphique Java. Les boutons de bascule Source
					et Design de la barre d'outils permettent d'afficher le code source d'une
					classe ou la vue graphique de ses composants d'interface. Les boutons
					supplémentaires permettent l'accès rapide aux commandes les plus
					fréquemment utilisées (activation des modes sélection ou connexion,
					alignement des composants, définition du comportement de
					redimensionnement automatique et aperçu des formulaires).
					La vue inspecteur est une représentation arborescente, visuelle et
					non visuelle, de tous les composants de votre application.</p>
                <p>L'inspecteur indique également les composants en cours de modification
					dans le générateur d'interface et permet d'organiser les composants dans
					les volets disponibles. La palette est la liste personnalisable des
					composants disponibles, comportant des onglets dédiés aux composants
					JFC/Swing, AWT et JavaBeans et aux gestionnaires de disposition. La fenêtre des propriétés
					affiche les propriétés du composant sélectionné dans le générateur d'interface, ainsi que
					dans les fenêtres Inspecteur, Projects et Files.</p>
                <p>
                    Matisse fonctionne avec un JAR supplémentaire
					nommé swing-layout-x.xjar où x.x est la version de la librairie. Ce jar contient
					le layout "révolutionnaire" appelé Free Design. Ce dernier est un modèle de disposition dynamique.
					Ainsi, le comportement des interfaces créées reste parfaitement identique au moment de leur exécution,
					vos modifications étant prises en compte sans incidence sur les relations définies entre les composants.
					Que vous redimensionniez le formulaire ou spécifiez un aspect différent, l'interface s'adapte
					automatiquement pour tenir compte des décalages de l'apparence ciblée.  L’inconvénient est que ce
					layout est non standard et qu’il vous impose de livrer le jar associé à ce layout dans votre application.
					Si le développeur souhaite visualiser son IHM sous un autre IDE, il ne pourra pas le faire. Au moment
					de déployer les applications, il faut vérifier que le jar swing-layout-x.x.jar se trouve dans le classpath.
					Cela évitera d’avoir des surprises lors du lancement de l’application.
                    <img src="./images/netbeans.jpg" />
                </p>
            </div>
            <p>
                Matisse ou Visual Editor offrent un outil de conception similaire. Nous retrouvons les mêmes vues d’une interface à l’autre.
				La différence se joue sur la gestion de la disposition des composants. Pour Visual Editor, le développeur devra choisir le
				layout qu’il souhaite utiliser. Si le layout est
                <em>null</em>
                , il ne faudra pas oublier de gérer le redimensionnement
				des composants. Or s’il développe sous Matisse, il ne se pose même pas la question concernant les layout. Enfin,
				nous pouvons avoir la situation que le développeur souhaite améliorer son GUI.
				S’il  l’a commencé sous Eclipse, il ne rencontrera pas de problème pour passer sous Matisse, mais le contraire ne fonctionne pas
				(sauf si vous ne souhaitez pas avoir de visualisation de l’interface graphique).
            </p>
        </div>
        <div class="chapter">
            <h2>Conclusion</h2>
            <p>Comme vous venez de le voir, il y a plusieurs possibilités pour créer son interface graphique.
				Pour choisir quels outils et quelles librairies utiliser, il vous faudra penser à la performance,
				à la portabilité et à l’évolutivité de votre code. De plus, comme nous l’avons souligné plus haut,
				certains outils sont très puissants, mais payants. A vous de définir votre besoin.</p>
        </div>
    </body>
</html>

